﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Winservice.demo
{
    class Logger
    {
        private static string logPath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\";//日志路径
        private readonly static object locker = new object();//同步锁，多线程解决方案

        /// <summary>
        /// 私有构造函数，防止实例化
        /// </summary>
        private Logger() { }

        /// <summary>
        /// 输出调试日志
        /// </summary>
        /// <param name="msg">日志消息</param>
        public static void Debug(string msg, string messageGroup = "")
        {
            Write(LogType.Debug, msg, messageGroup);
        }

        /// <summary>
        /// 输出基础日志
        /// </summary>
        /// <param name="msg">日志消息</param>
        public static void Info(string msg, string messageGroup = "")
        {
            Write(LogType.Info, msg, messageGroup);
        }

        /// <summary>
        /// 输出警告日志
        /// </summary>
        /// <param name="msg"></param>
        public static void Warn(string msg, string messageGroup = "")
        {
            Write(LogType.Warn, msg, messageGroup);
        }

        /// <summary>
        /// 输出错误日志
        /// </summary>
        /// <param name="msg">日志消息</param>
        /// <param name="e">异常对象</param>
        public static void Error(string msg, Exception e = null, string messageGroup = "")
        {
            Write(LogType.Error, msg, messageGroup, e);
        }

        /// <summary>
        /// 输出控制台日志
        /// </summary>
        /// <param name="msg">日志消息</param>
        public static void Console(string msg, string messageGroup = "")
        {
            //Console.WriteLine("Exception：" + msg);
            //Console.WriteLine("按任意键继续...");
            //Console.ReadLine();
        }

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="type">日志类型</param>
        /// <param name="msg">日志消息</param>
        /// <param name="e">异常对象</param>
        private static void Write(LogType type, string msg, string messageGroup, Exception e = null)
        {
            string configType = ConfigurationManager.AppSettings["LogType"];

            #region 日志类型判断
            string logType = "";
            switch (type)
            {
                case LogType.Debug:
                    logType = "Debug";
                    break;
                case LogType.Info:
                    logType = "Info";
                    break;
                case LogType.Warn:
                    logType = "Warn";
                    break;
                case LogType.Error:
                    logType = "Error";
                    break;
            }

            if (configType != null && configType.ToLower() != "all" && configType.ToLower().IndexOf(logType.ToLower()) < 0)
            {
                return;
            }
            #endregion

            #region 写日志
            StreamWriter writer = null;
            try
            {
                if (!string.IsNullOrEmpty(messageGroup))
                {
                    messageGroup += "\\";
                }

                //创建日志文件
                string path = logPath + messageGroup + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
                string dir = System.IO.Path.GetDirectoryName(path);
                if (!System.IO.Directory.Exists(dir))
                {
                    System.IO.Directory.CreateDirectory(dir);
                }

                //写入日志内容
                lock (locker)
                {
                    writer = new StreamWriter(path, true);
                    if (e != null)
                    {
                        msg += ":" + e.Message + e.StackTrace;
                    }

                    writer.WriteLine("[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "] [" + type + "]\t" + msg);
                }

                //结束写入
                writer.Flush();
                writer.Close();
            }
            catch
            {
                writer.Close();
            }
            finally
            {
                writer.Close();
            }
            #endregion
        }

        /// <summary>
        /// 日志类型
        /// </summary>
        public enum LogType
        {
            /// <summary>
            /// 调试日志
            /// </summary>
            Debug,
            /// <summary>
            /// 基础日志
            /// </summary>
            Info,
            /// <summary>
            /// 警告日志
            /// </summary>
            Warn,
            /// <summary>
            /// 错误日志
            /// </summary>
            Error
        }
    }
}
